package models

import (
	"context"
	"errors"
)

// Insert 通用插入
// ctx 上下文
// data 数据
func Insert(ctx context.Context, data interface{}) (int64, error) {
	pos, err := getSession(ctx).Insert(data)
	if err != nil {
		return 0, err
	}
	return pos, nil
}

// BatchInsert 通用批量插入
// ctx 上下文
// data 数据切片
func BatchInsert(ctx context.Context, data interface{}) (int64, error) {
	pos, err := getSession(ctx).Insert(data)
	if err != nil {
		return 0, err
	}
	return pos, nil
}

// Update 通用修改
// ctx 上下文
// condition 条件
// data 修改数据
// fields 修改字段
func Update(ctx context.Context, condition string, data interface{}, fields ...string) error {
	if condition == "" {
		return errors.New("condition missing")
	}
	session := getSession(ctx).Where(condition)
	if len(fields) > 0 {
		session = session.Cols(fields...)
	}
	_, err := session.Update(data)
	return err
}

// BatchUpdateByIds 通用修改
// ctx 上下文
// condition 条件
// data 修改数据
// fields 修改字段
func BatchUpdateByIds(ctx context.Context, condition string, data interface{}, ids []interface{}, fields ...string) error {
	if condition == "" {
		return errors.New("condition missing")
	}
	if len(ids) == 0 {
		return errors.New("ids missing")
	}
	session := getSession(ctx).In("id", ids).Where(condition)
	if len(fields) > 0 {
		session = session.Cols(fields...)
	}
	_, err := session.Update(data)
	return err
}

// Delete 通用删除
// ctx 上下文
// data 删除条件
func Delete(ctx context.Context, data interface{}, condition string) error {
	_, err := getSession(ctx).Where(condition).Delete(data)
	if err != nil {
		return err
	}
	return nil
}

// Get 通用单条查询
// ctx 上下文
// data 查询结果
// condition 查询条件
// args 条件参数
func Get(ctx context.Context, data interface{}, condition string, args ...interface{}) (bool, error) {
	return getSession(ctx).Where(condition, args...).Get(data)
}

// Find 通用多条查询
// ctx 上下文
// data 查询结果切片指针
// condition 查询条件
// args 条件参数
func Find(ctx context.Context, data interface{}, condition string, args ...interface{}) error {
	return getSession(ctx).Where(condition, args...).Find(data)
}

// FindByPage 通用分页查询
// ctx 上下文
// data 查询结果切片指针
// page 页码
// pageSize 每页大小
// condition 查询条件
// args 条件参数
func FindByPage(ctx context.Context, data interface{}, page, pageSize int, condition string, args ...interface{}) (int64, error) {
	session := getSession(ctx).Where(condition, args...)
	count, err := session.Limit(pageSize, (page-1)*pageSize).FindAndCount(data)
	return count, err
}

// Count 通用统计
// ctx 上下文
// data 查询对象
// condition 查询条件
// args 条件参数
func Count(ctx context.Context, data interface{}, condition string, args ...interface{}) (int64, error) {
	return getSession(ctx).Where(condition, args...).Count(data)
}

// Exists 通用存在性检查
// ctx 上下文
// data 查询对象
// condition 查询条件
// args 条件参数
func Exists(ctx context.Context, data interface{}, condition string, args ...interface{}) (bool, error) {
	count, err := Count(ctx, data, condition, args...)
	return count > 0, err
}

// Exec 执行原生SQL
func Exec(ctx context.Context, sql string, args ...interface{}) (int64, error) {
	result, err := getSession(ctx).Exec(sql, args)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}
